package lec04.pm.gm.v2;

public class UniLinkedList {
	Node head, tail;
	int size;

	public UniLinkedList() {
		this.head = new Node(-1);
		this.tail = new Node(-1);
		this.head.setNext(this.tail);
		this.size = 0;

	}

	 static class Node {
		public Node(int elem) {
			this.elem = elem;
			this.next = null;
		}

		public void setNext(Node next) {
			this.next = next;

		}

		int elem;

		public int getElem() {
			return elem;
		}

		public void setElem(int elem) {
			this.elem = elem;
		}

		public Node getNext() {
			return next;
		}

		Node next;
	}

	public static void main(String[] args) {
		UniLinkedList list = new UniLinkedList();
		for (int i = 0; i < 10; i++) {
			Node node = new Node(i);
			if (i % 2 == 0)
				list.append(node);
			else
				list.prepend(node);
			System.out.println(list);

		}
		for (int i = 0; i < 10; i++) {
			if (i % 2 == 0)
				list.popFirst();
			else
				list.popLast();
			System.out.println(list);

		}
	}

	public boolean popLast() {
		if (this.isEmpty())
			return false;
		Node last = this.head;
		while (last.next != this.tail)
			last = last.next;
		last.next = null;
		this.tail = last;
		--this.size;
		return true;

	}

	public boolean popFirst() {
		if (this.isEmpty())
			return false;
		Node headNext = head.next;
		head.next = null;
		head = headNext;
		--this.size;
		return true;

	}

	public void append(Node node) {
		Node last = this.head;
		while (last.next != this.tail)
			last = last.next;
		last.next = node;
		node.next = this.tail;
		++this.size;

	}

	public void prepend(Node node) {
		Node headNext = head.next;
		head.next = node;
		node.next = headNext;
		++this.size;

	}

	@Override
	public String toString() {
		if (this.isEmpty())
			return "[]";
		StringBuffer buffer = new StringBuffer("[");

		for (Node node = head.next; node != tail; node = node.next)
			buffer.append(node.getElem() + ",");
		buffer.deleteCharAt(buffer.length()-1);
		buffer.append(']');

		return buffer.toString();
	}

	private boolean isEmpty() {
		return this.size == 0;
	}
}
